package cn.jhz.learn.community_dynamic.app.websocket;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.jose4j.jws.JsonWebSignature;
import org.jose4j.jwx.JsonWebStructure;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.web.authentication.www.NonceExpiredException;
import org.springframework.stereotype.Component;
import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.server.HandshakeInterceptor;

import cn.jhz.learn.community_dynamic.security.helper.LoginHelper;
import cn.jhz.learn.community_dynamic.security.manager.JwtManager;
import cn.jhz.learn.community_dynamic.security.model.AccountType;
import cn.jhz.learn.community_dynamic.security.service.JsonUserDetailsService;

@Component
public class ConnectHandshakeInterceptor implements HandshakeInterceptor {

    private final JwtManager JwtManager;
    private final JsonUserDetailsService userService;

    @Autowired
    public ConnectHandshakeInterceptor(JwtManager jwtManager, JsonUserDetailsService userService) {
	super();
	this.JwtManager = jwtManager;
	this.userService = userService;
    }

    /**
     * 1.过滤没有TOKEN的连接 2.解析TOKEN及相关信息放入attributes
     */
    @Override
    public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
	    Map<String, Object> attributes) throws Exception {
	System.out.println("beforeHandshake");

	HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest();
	// 从头中获取token并封装后提交给AuthenticationManager
	try {
	    String token = getJwtToken(servletRequest);
	    UserDetails user;
	    if (StringUtils.isNotBlank(token)) {
		LoginHelper.setAccountType(AccountType.JWT);
		JsonWebStructure structure = JsonWebSignature.fromCompactSerialization(token);
		user = userService
			.loadUserByUsername(this.JwtManager
				.validate(token,
					this.JwtManager.rsaJsonWebKey(null, structure.getKeyIdHeaderValue())
						.orElseThrow(() -> new UsernameNotFoundException("Error Token")))
				.getSubject());
		if (user == null || user.getPassword() == null)
	                throw new NonceExpiredException("Token expires");
		else {
		    attributes.put("user", LoginHelper.getLoginUser().get());
		}
		return true;
	    }
	} catch (Exception e) {
	    e.printStackTrace();
	    return false;
	}
	return false;
    }

    @Override
    public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
	    Exception exception) {
	System.out.println("afterHandshake");
    }

    private String getJwtToken(HttpServletRequest request) {
	String authInfo = request.getParameter("token");
	return StringUtils.removeStart(authInfo, "Bearer ");
    }

}
